package com.smartalarmclock.Logic;

import java.lang.reflect.Method;

import com.android.internal.telephony.ITelephony;
import com.smartalarmclock.Model.ContactFactory;
import com.smartalarmclock.Model.IAutoResponse;
import com.smartalarmclock.Model.ILogEntry;
import com.smartalarmclock.Model.IProfile;
import com.smartalarmclock.Model.ISingleContact;
import com.smartalarmclock.Model.LogEntryFactory;
import com.smartalarmclock.Model.Exceptions.ConflictingSchedueledProfilesException;
import com.smartalarmclock.Model.Exceptions.DataEntityDoesNotExistException;
import com.smartalarmclock.Model.Exceptions.InvalidSaveDataEntityOperationException;
import com.smartalarmclock.Model.Exceptions.PhoneContactDoesNotExistException;
import com.smartalarmclock.Model.ILogEntry.PhoneEvent;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.util.Log;

public class PhoneCallBroadcastReceiver extends BroadcastReceiver {
	Context context = null;
 	private static final String TAG = "Phone call";
 	private ITelephony telephonyService;
 	
 	@Override
 	public void onReceive(Context context, Intent intent) {
 		Bundle bundle = intent.getExtras();
 		String phoneNr= bundle.getString("incoming_number");
 		
 		Log.v(TAG, "Receving.... phoneNr: "+phoneNr);
  
 		TelephonyManager telephony = (TelephonyManager) 
 				context.getSystemService(Context.TELEPHONY_SERVICE);  
 		try {
 			Class<?> c = Class.forName(telephony.getClass().getName());
 			Method m = c.getDeclaredMethod("getITelephony");
 			m.setAccessible(true);
 			telephonyService = (ITelephony) m.invoke(telephony);
 			
 			Log.v(TAG, "Attempting to get autoResponse for " + phoneNr);
 			IAutoResponse autoResponse = AcAutoResponseService.AcAutoResponseServiceStatic.GetAutoResponseForContact(phoneNr, context);
 			
 			if (autoResponse != null)
 			{
 	 			Log.d(TAG, "Auto response found for " + phoneNr);
 				if (autoResponse.IsBlocking())
 				{
 					Log.d(TAG, "Decided to block " + phoneNr);
 					telephonyService.endCall();
 				}
 				
 				if (autoResponse.IsSendingAutoSMS())
 				{
 					Log.d(TAG, "Sending SMS to " + phoneNr);
 					sendSMS(phoneNr, autoResponse.GetAutoSMS().GetMessage());
 				}
 			}
 			else
 			{
 	 			Log.v(TAG, "Auto response is null! profile shouldn't be running then...");
 			}
 			
 			writeToSACLog(context, phoneNr, autoResponse);
 			
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
  
 	}
 	
 	private void writeToSACLog(Context context, String phoneNr, IAutoResponse autoResponse)
 	{
 		LogEntryFactory logEntryFactory = new LogEntryFactory();
 		ISingleContact contactCalling = null;
		ContactFactory contactFactory = new ContactFactory();
		try {
			contactCalling = contactFactory.GetSingleContactByPhoneNumber(context, phoneNr);
		} catch (DataEntityDoesNotExistException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (PhoneContactDoesNotExistException e1) {
			Log.v(TAG, "Contact doesn't exist in phonebook");
			contactCalling = null;
		}
		
		// TODO: Calling running profile twice can be problematic if called exactly when switching profiles. Fix this.
		IProfile profile = null;
		try {
			profile = AcManager.GetInstance().GetRunningProfile(context, false);
		} catch (ConflictingSchedueledProfilesException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		ILogEntry logEntry = null;
		if (contactCalling != null)
		{
			logEntry = logEntryFactory.CreateLogEntry(PhoneEvent.IncomingCall, false, contactCalling, profile, autoResponse.GetAutoSMS().GetMessage());
		}
		else
		{
			logEntry = logEntryFactory.CreateLogEntry(PhoneEvent.IncomingCall, false, phoneNr, profile, autoResponse.GetAutoSMS().GetMessage());
		}
		
		try {
			logEntry.Save(context);
		} catch (InvalidSaveDataEntityOperationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
 	}
 	
 	public void sendSMS(String i_PhoneNumber, String i_Response) {

 	    SmsManager smsManager = SmsManager.getDefault();
 	    smsManager.sendTextMessage(i_PhoneNumber, null, i_Response, null, null);
 	}
}